//Hung Nguyen 
//Jeremy Sardoma
//Matthew Alcazar

//Camera Class borrowed from...
//http://www.codecolony.de/opengl.htm

#include <stdio.h>  
#include <gl\glut.h>
#include <math.h>
#include <iostream>
#include <Windows.h>
#include "camera.h"

Struct3dVector Float3dVector(GLfloat x, GLfloat y, GLfloat z) {
	Struct3dVector tmp;
	tmp.x = x;
	tmp.y = y;
	tmp.z = z;
	return tmp;
}
Struct3dVector Add3dVector(Struct3dVector *u, Struct3dVector *v) {
	Struct3dVector result;
	result.x = u->x + v->x;
	result.y = u->y + v->y;
	result.z = u->z + v->z;
	return result;
}
void Add3dVectorToVector(Struct3dVector *dst, Struct3dVector *v2) {
	dst->x += v2->x;
	dst->y += v2->y;
	dst->z += v2->z;
}

Camera::Camera() {
	Position = Float3dVector(0.0, 0.0, 0.0);
	Direction = Float3dVector(0.0, 0.0, -1.0);

	turbo = false;
	gravity = false;
	ViewDirChanged = false;

	XRot = YRot = ZRot = 0;
}

void Camera::GetViewDir(void) {
	Struct3dVector p1, p2;
	//rotate around y-axis
	p1.x = cos((YRot + 90.0) * (3.141592/180));
	p1.z = -sin((YRot + 90.0) * (3.141592/180));
	//rotate around x-axis
	double cosX = cos(XRot * (3.141592/180));
	p2.x = p1.x * cosX;
	p2.y = sin(XRot * (3.141592/180));
	p2.z = p1.z * cosX;
	
	Direction = p2;
}

void Camera::Move(Struct3dVector Direction) {
	Add3dVectorToVector(&Position, &Direction);
}

void Camera::RotateY(GLfloat Angle) {
	YRot += Angle;
	glRotatef(Angle, 0, 1, 0);
	if(Angle>180) Angle=Angle-360;
	if(Angle<-180) Angle = Angle+360;
	ViewDirChanged = true;
}

void Camera::RotateX(GLfloat Angle) {
	XRot += Angle;
	//glRotatef(XRot, 1, 0, 0);
	if(Angle>180) Angle=Angle-360;
	if(Angle<-180) Angle = Angle+360;
	ViewDirChanged = true;
}

void Camera::RotateZ(GLfloat Angle) {
	ZRot += Angle;
	if(Angle>180) Angle=Angle-360;
	if(Angle<-180) Angle = Angle+360;
	ViewDirChanged = true;
}


void Camera::Render(void) {
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glRotatef(-XRot, 1.0, 0.0, 0.0);
	glRotatef(-YRot, 0.0, 1.0, 0.0);
	glRotatef(-ZRot, 0.0, 0.0, 1.0);
	glTranslatef(-Position.x, -Position.y, -Position.z);

}

void Camera::Forward(GLfloat Distance) {
	if(turbo==true) 
		Distance = Distance * 4;
	if(ViewDirChanged) 
		GetViewDir();
	Struct3dVector MoveVector;
	
	MoveVector.x = Direction.x * -Distance;
	MoveVector.y = Direction.y * -Distance;
	MoveVector.z = Direction.z * -Distance;
	Add3dVectorToVector(&Position, &MoveVector);
}

void Camera::StrafeRight(GLfloat Distance) {
	if(ViewDirChanged)
		GetViewDir();
	Struct3dVector MoveVector;
	MoveVector.z = -Direction.x * -Distance;
	MoveVector.y = 0.0;
	MoveVector.x = Direction.z * -Distance;
	Add3dVectorToVector(&Position, &MoveVector);
}

void Camera::Up(GLfloat Distance) {
	if(ViewDirChanged)
		GetViewDir();
	Struct3dVector MoveVector;
	MoveVector.z = 0.0;
	MoveVector.y = Direction.z * -Distance;
	MoveVector.x = 0.0;
	Add3dVectorToVector(&Position, &MoveVector);
}



